
--------------获取文本文件行列表-------------------------------
function texteditor_read_txt()
	
	local input = io.open(TEXTEDITOR_FILE_PATH, "rb")
	if input == nil then
		return -1
	end

	input:seek("set", texteditor_read_pos)

	local limit_width = texteditorFunc.getTextWidth()
	local read_bytes = 512
	local read_data = nil
	local read_line_counts = 0
	local read_line_str = nil
	local read_width = 0
	local check_last_pos = 0
	local check_break_pos = 0
	local previous_data = nil
	while true do
		read_data = input:read(read_bytes)
		if read_data == nil and previous_data == nil then
			break
		end
		if previous_data then
			read_data = previous_data..read_data
			previous_data = nil
		end
		
		local read_data_len = #read_data
		check_last_pos = 0
		check_break_pos = 0
		local i = 1
		while i <= read_data_len do
			if not read_line_str then
				read_line_str = ""
			end
			local curByte = string.byte(read_data, i)
			local byte_count = 1
			if curByte > 0 and curByte <= 127 then
				byte_count = 1
			elseif curByte >= 192 and curByte <= 223 then
				byte_count = 2
			elseif curByte >= 224 and curByte <= 239 then
				byte_count = 3
			elseif curByte >= 240 and curByte <= 247 then
				byte_count = 4
			end
			check_last_pos = i + byte_count - 1
			if check_last_pos > read_data_len then
				if texteditor_read_pos + check_last_pos < texteditor_file_size then
					check_last_pos = i - 1
					previous_data = string.sub(read_data, i, read_data_len)
					break
				else
					check_last_pos = read_data_len
				end
			end
			while true do
				local c = string.sub(read_data, i, check_last_pos)
				if c == "\r" and check_last_pos < read_data_len then
					local next_pos = check_last_pos + 1
					local c_next = string.byte(read_data, next_pos, next_pos)
					if c_next == "\n" then
						check_last_pos = next_pos
						check_break_pos = check_last_pos
						local linebreak_str = c..c_next
						local line_info = {text = read_line_str, linebreak = linebreak_str}
						table.insert(texteditor_list, line_info)
						texteditor_list_len += 1
						read_line_counts += 1
						read_line_str = nil
						read_width = 0
						break
					end
				elseif c == "\n" then
					check_break_pos = check_last_pos
					local linebreak_str = c
					local line_info = {text = read_line_str, linebreak = linebreak_str}
					table.insert(texteditor_list, line_info)
					texteditor_list_len += 1
					read_line_counts += 1
					read_line_str = nil
					read_width = 0
					break
				end
				local c_width = screen.textwidth(c, 1)
				read_width += c_width
				if read_width > limit_width then
					local line_info = {text = read_line_str, linebreak = nil}
					table.insert(texteditor_list, line_info)
					check_break_pos = check_last_pos
					texteditor_list_len += 1
					read_line_counts += 1
					read_line_str = c
					read_width = c_width
				else
					read_line_str = read_line_str..c
				end
				break
			end
			i = check_last_pos + 1
		end
		texteditor_read_pos += check_last_pos
		if read_line_counts >= 100 then
			break			
		end
	end
	if texteditor_read_pos >= texteditor_file_size then
		if read_line_str then
			local line_info = {text = read_line_str, linebreak = nil}
			table.insert(texteditor_list, line_info)
			texteditor_list_len += 1
			read_line_counts += 1			
		end
	else
		if check_break_pos < check_last_pos then
			texteditor_read_pos -= (check_last_pos - check_break_pos)
		end
	end
	input:close()
	
	return 1
 
end

--------------获取sfo文件行列表-------------------------------
function texteditor_read_sfo()
	
	local sfo_data = game.info(TEXTEDITOR_FILE_PATH)
	if not sfo_data then
		return -1
	end
	if sfo_data.TITLE then
		sfo_data.TITLE = string.gsub(sfo_data.TITLE, "\n"," ")
	end
	if sfo_data.STITLE then
		sfo_data.STITLE = string.gsub(sfo_data.STITLE, "\n"," ")
	end
	for k, v in pairs(sfo_data) do
		local mText = tostring(k).." = "..tostring(v)
		local lineInfo = {text = mText, linebreak_str = nil}
		table.insert(texteditor_list, lineInfo)
	end
	table.sort(texteditor_list, function(a, b) return string.lower(a.text) < string.lower(b.text) end)
	texteditor_read_pos = texteditor_file_size
	texteditor_list_len = #texteditor_list
	texteditor_need_refresh = true
	
	return 1

end

--------------获取文件行列表-------------------------------
function texteditor_get_list()
 
	WaitDialog(WAIT_LOADING)
	
	texteditor_list = {}
	local ret = -1
	if files.ext(TEXTEDITOR_FILE_PATH) == "sfo" then
		ret = texteditor_read_sfo()
		if ret < 0 then
			MessageDialog(TIPS, TEXTEDITOR_OPEN_SFO_FAILED, BACK)
			texteditor_exit()		
		end
	else
		ret = texteditor_read_txt()
		if ret < 0 then
			MessageDialog(TIPS, TEXTEDITOR_OPEN_TXT_FAILED, BACK)
			texteditor_exit()		
		end
	end
	texteditor_need_refresh = true
	
	dismissDialog()

end

----------------编辑行----------------------------
function texteditor_edit_line()

	if TEXTEDITOR_OPEN_MODE == __READ then
		return -1
	end

	if not texteditor_list then
		return -1
	end
	
	if texteditor_list_len < 1 then
		return -1
	end
	
	local edit_str = texteditor_list[texteditor_pos].text
	local new_str = osk.init(TEXTEDITOR_PLEASE_INPUT, edit_str)
	if not new_str or new_str == edit_str then
		return
	end
	local limit = texteditorFunc.getLimit()
	local current_linebreak_str = texteditor_list[texteditor_pos].linebreak
	local line_str = new_str..(current_linebreak_str or "")
	table.remove(texteditor_list, texteditor_pos)
	texteditor_list_len -= 1
	local scan_pos = texteditor_pos
	while (not current_linebreak_str and scan_pos <= texteditor_list_len) do
		if texteditor_top + limit > texteditor_list_len and texteditor_read_pos < texteditor_file_size then
			texteditor_read_txt()
			texteditor_list_len = #texteditor_list
		end

		current_linebreak_str = texteditor_list[scan_pos].linebreak
		line_str = line_str..texteditor_list[scan_pos].text..(current_linebreak_str or "")
		table.remove(texteditor_list, scan_pos)
		texteditor_list_len -= 1
	end

	local current_list = {}
	local limit_width = texteditorFunc.getTextWidth()
	breakStringByWidth(current_list, line_str, limit_width)
	local current_list_len = #current_list
	local insert_pos = texteditor_pos
	for i = 1, current_list_len do
		table.insert(texteditor_list, insert_pos, current_list[i])
		insert_pos += 1
	end
	texteditor_list_len += current_list_len
	__TEXTEDITOR_MODIFIED = true
	texteditor_need_refresh = true

end

----------------添加行----------------------------
function texteditor_insert_line()

  if TEXTEDITOR_OPEN_MODE == __READ then
		return -1
	end
	
	if not texteditor_list then
		texteditor_list = {}
	end
	
	local insert_pos = texteditor_pos
	if texteditor_list_len < 1 then
		insert_pos = 1
	else
		if buttons.down or buttons.analogly > 60 then
			insert_pos += 1
		end
		local insert_linebreak_str = "\n"
		if insert_pos <= texteditor_list_len then
			insert_linebreak_str = texteditor_list[insert_pos].linebreak
		end
		local previous_pos = insert_pos - 1
		if previous_pos > 0 then
			local previous_linebreak_str = texteditor_list[previous_pos].linebreak
			if not previous_linebreak_str then
				texteditor_list[previous_pos].linebreak = insert_linebreak_str
			end
		end
	end
	table.insert(texteditor_list, insert_pos, {text = "", linebreak = "\n"})
	texteditor_pos = insert_pos
	texteditor_list_len += 1	
	__TEXTEDITOR_MODIFIED = true
	texteditor_need_refresh = true  

end

----------------删除行----------------------------
function texteditor_remove_line()

	if TEXTEDITOR_OPEN_MODE == __READ then
		return -1
	end
	
	if not texteditor_list then
		return -1
	end
	
	local limit = texteditorFunc.getLimit()
	if texteditor_top + limit > texteditor_list_len and texteditor_read_pos < texteditor_file_size then
		texteditor_read_txt()
		texteditor_list_len = #texteditor_list
	end
  
	if texteditor_list_len < 1 then
		return -1
	end

	--删除行
	local previous_pos = texteditor_pos - 1
	if previous_pos > 0 then
		local current_linebreak_str = texteditor_list[texteditor_pos].linebreak
		local previous_linebreak_str = texteditor_list[previous_pos].linebreak
		if current_linebreak_str and not previous_linebreak_str then
			texteditor_list[previous_pos].linebreak = current_linebreak_str
		end
	end
	table.remove(texteditor_list, texteditor_pos)  
	texteditor_list_len -= 1
	__TEXTEDITOR_MODIFIED = true
  texteditor_need_refresh = true

end
----------------光标上移----------------------------
function texteditor_scroll_up()

	if not texteditor_list then
		return -1
	end
  
	if texteditor_list_len < 1 then
		return -1
	end

	if texteditor_pos then
		if texteditor_pos > 1 then
			texteditor_pos -= 1
			texteditor_need_refresh = true
		end
	else
		if texteditor_top > 1 then
			texteditor_top -= 1
			texteditor_need_refresh = true
		end
	end

end

----------------光标下移----------------------------
function texteditor_scroll_down()

	if not texteditor_list then
		return -1
	end

	local limit = texteditorFunc.getLimit()
	local tmpTop = texteditor_top + 1
	if tmpTop + (limit - 1) > texteditor_list_len and texteditor_read_pos < texteditor_file_size then
		texteditor_read_txt()
		texteditor_list_len = #texteditor_list
	end
  
	if texteditor_list_len < 1 then
		return -1
	end
	
	if texteditor_pos then
		if texteditor_pos < texteditor_list_len then
			texteditor_pos += 1
			texteditor_need_refresh = true
		end
	else
		if texteditor_top < texteditor_list_len - (limit-1) then
			texteditor_top += 1
			texteditor_need_refresh = true
		end
	end
	
	return

end

----------------跳转上一页----------------------------
function texteditor_skip_previous_page()

	if not texteditor_list then
		return -1
	end
  
	if texteditor_list_len < 1 then
		return -1
	end

	local limit = texteditorFunc.getLimit()
	if texteditor_top > 1 then
		texteditor_top -= limit
		if texteditor_pos then
			texteditor_pos -= limit
		end
		texteditor_need_refresh = true
	end

end

----------------跳转下一页----------------------------
function texteditor_skip_next_page()

	if not texteditor_list then
		return -1
	end
	
	local limit = texteditorFunc.getLimit()
	local tmpTop = texteditor_top + limit
	if tmpTop + (limit - 1) > texteditor_list_len and texteditor_read_pos < texteditor_file_size then
		texteditor_read_txt()
		texteditor_list_len = #texteditor_list
	end
  
	if texteditor_list_len < 1 then
		return -1
	end
	
	if texteditor_top < texteditor_list_len - (limit - 1) then
		texteditor_top += limit
		if texteditor_pos then
		texteditor_pos += limit
		end
		texteditor_need_refresh = true
	end
	
	return 1
	
end

--------------保存文本-------------------------------
function texteditor_save_txt()
 
	lock_home_key()
	WaitDialog(TEXTEDITOR_SAVING)

	local srcPath = TEXTEDITOR_FILE_PATH
	local srcName = getFileName(srcPath)
	local dstPath = srcPath
	local input = nil
	if texteditor_read_pos < texteditor_file_size then
		dstPath = getRootPath(srcPath).."/temp/"..srcName..".temp"
		deletePath(dstPath)
		input = io.open(srcPath, "rb")
		if input == nil then
			unlock_home_key()
			WaitDialog(TEXTEDITOR_SAVE_FAILED)
			os.delay(200)
			dismissDialog()
		end
	end
	local output = io.open(dstPath, "wb+")
	if output == nil then
		if input ~= nil then
			input:close()
		end
		unlock_home_key()
		WaitDialog(TEXTEDITOR_SAVE_FAILED)
		os.delay(200)
		dismissDialog()
	end
	--写入已读取的部分
	for i = 1, #texteditor_list do
		local line = texteditor_list[i].text..(texteditor_list[i].linebreak or "")
		output:write(line)
		output:flush()
	end
	--写入未读取的后部分
	if texteditor_read_pos < texteditor_file_size then
		input:seek("set", texteditor_read_pos)
		local read_bytes = 64*1024
		while true do
			local read_data = input:read(read_bytes)
			if read_data == nil then
				break
			end
			output:write(read_data)
			output:flush()
		end
		deletePath(srcPath)
		files.rename(dstPath, srcName)
		dstPath = getParentPath(dstPath)..srcName
		movePath(dstPath, getParentPath(srcPath))
	end
	if input ~= nil then
		input:close()
	end
	if output ~= nil then
		output:close()
	end

	unlock_home_key()
	WaitDialog(TEXTEDITOR_SAVE_COMPLETED)
	os.delay(200)
	dismissDialog()
 
end

----------------退出文本编辑器----------------------------
function texteditor_exit()

	if __TEXTEDITOR_MODIFIED then
		local state = MessageDialog(TIPS, TEXTEDITOR_EXIT_SAVE_READY, BACK, TEXTEDITOR_BUTTON_SAVE, TEXTEDITOR_BUTTON_UNSAVE)
		if state == 0 then --取消
			return
		elseif state == 1 then --保存后退出
			texteditor_save_txt()
			if explorer_list then
				explorer_get_filelist()
			end
		end
	end
	texteditor_list = nil
	table.remove(MATH_FUNC, #MATH_FUNC)
 
end


